from __future__ import annotations

from PySide2.QtCore import Qt, QTimer
from PySide2.QtWidgets import (
    QWidget,
    QVBoxLayout,
    QHBoxLayout,
    QLabel,
    QLineEdit,
    QPushButton,
    QFrame,
    QFormLayout,
)
from PySide2.QtGui import QIcon

from mooetoolapp.handlercore.language_manager import LanguageManager
from mooetoolapp.threadcore.websocket_bridge_client import WebSocketBridgeClient
from gglobal import logger
import time


class CarStatusWindow(QWidget):
    """车辆状态查看窗口（仅UI，功能暂不实现）"""

    def __init__(self, parent: QWidget | None = None, language_manager: LanguageManager | None = None) -> None:
        super().__init__(parent)
        # 语言管理器（用于多语言文本）
        self.language_manager = language_manager or LanguageManager()

        # 基本窗口属性
        # 为QSS样式适配使用已有样式ID
        self.setObjectName("settings_window")
        self.setWindowFlags(Qt.Window | Qt.WindowCloseButtonHint | Qt.WindowMinMaxButtonsHint)
        self.setWindowModality(Qt.ApplicationModal)
        self.setAttribute(Qt.WA_DeleteOnClose, True)
        try:
            self.setWindowIcon(QIcon(":/icon/vehiclestatus.svg"))
        except Exception:
            pass

        # 设置窗口标题（支持多语言）
        title = self.language_manager.get_text("car_status_window_title", "车辆状态")
        self.setWindowTitle(title)

        # 主布局
        main_layout = QVBoxLayout(self)
        main_layout.setContentsMargins(16, 16, 16, 16)
        main_layout.setSpacing(12)

        # 顶部：IP输入与连接开关
        top_frame = QFrame(self)
        top_layout = QHBoxLayout(top_frame)
        top_layout.setContentsMargins(0, 0, 0, 0)
        top_layout.setSpacing(8)

        ip_label = QLabel(self.language_manager.get_text("car_status_ip_label", "车辆IP"), top_frame)
        ip_label.setObjectName("vehicle_ip_label")
        self.ip_edit = QLineEdit(top_frame)
        self.ip_edit.setObjectName("settings_input")
        self.ip_edit.setPlaceholderText(self.language_manager.get_text("car_status_ip_placeholder", "请输入车辆IP地址"))

        self.connect_button = QPushButton(top_frame)
        self.connect_button.setObjectName("connect_button")
        self.connect_button.setCheckable(True)
        self.connect_button.setChecked(False)
        self._update_connect_button_text(False)
        # 功能暂不实现，仅切换按钮文本
        self.connect_button.toggled.connect(self._on_connect_toggled)

        top_layout.addWidget(ip_label)
        top_layout.addWidget(self.ip_edit, stretch=1)
        top_layout.addWidget(self.connect_button)
        main_layout.addWidget(top_frame)

        # 状态区域：表单布局展示关键字段
        status_frame = QFrame(self)
        status_frame.setObjectName("function_button_frame")
        status_layout = QFormLayout(status_frame)
        status_layout.setFormAlignment(Qt.AlignLeft | Qt.AlignTop)
        status_layout.setContentsMargins(0, 0, 0, 0)
        status_layout.setSpacing(8)

        self.label_robotid = QLabel("—", status_frame)
        self.label_robotverion = QLabel("—", status_frame)
        self.label_robotspeed = QLabel("—", status_frame)
        self.label_obs = QLabel("—", status_frame)
        self.label_charge = QLabel("—", status_frame)
        self.label_errorcode = QLabel("—", status_frame)

        self._lab_robotid_title = QLabel(self.language_manager.get_text("car_status_robotid", "车辆ID"), status_frame)
        self._lab_robotverion_title = QLabel(self.language_manager.get_text("car_status_robotverion", "车辆版本"), status_frame)
        self._lab_robotspeed_title = QLabel(self.language_manager.get_text("car_status_robotspeed", "车辆速度"), status_frame)
        self._lab_obs_title = QLabel(self.language_manager.get_text("car_status_obs", "车辆避让状态"), status_frame)
        self._lab_charge_title = QLabel(self.language_manager.get_text("car_status_charge", "车辆电量"), status_frame)
        self._lab_errorcode_title = QLabel(self.language_manager.get_text("car_status_errorcode", "故障码信息"), status_frame)

        status_layout.addRow(self._lab_robotid_title, self.label_robotid)
        status_layout.addRow(self._lab_robotverion_title, self.label_robotverion)
        status_layout.addRow(self._lab_robotspeed_title, self.label_robotspeed)
        status_layout.addRow(self._lab_obs_title, self.label_obs)
        status_layout.addRow(self._lab_charge_title, self.label_charge)
        status_layout.addRow(self._lab_errorcode_title, self.label_errorcode)

        main_layout.addWidget(status_frame)

        # 设置初始大小
        self.resize(520, 360)

        # 注册静态文本以支持语言切换
        try:
            self.language_manager.register_widget(self, "car_status_window_title", property_name="windowTitle")
            # 注册控件以支持中英文切换
            self.language_manager.register_widget(ip_label, "car_status_ip_label", property_name="text")
            self.language_manager.register_widget(self.ip_edit, "car_status_ip_placeholder", property_name="placeholderText")
            self.language_manager.register_widget(self._lab_robotid_title, "car_status_robotid", property_name="text")
            self.language_manager.register_widget(self._lab_robotverion_title, "car_status_robotverion", property_name="text")
            self.language_manager.register_widget(self._lab_robotspeed_title, "car_status_robotspeed", property_name="text")
            self.language_manager.register_widget(self._lab_obs_title, "car_status_obs", property_name="text")
            self.language_manager.register_widget(self._lab_charge_title, "car_status_charge", property_name="text")
            self.language_manager.register_widget(self._lab_errorcode_title, "car_status_errorcode", property_name="text")
            # 语言切换时同步更新连接按钮文案
            self.language_manager.language_changed.connect(lambda *_: self._update_connect_button_text(self.connect_button.isChecked()))
        except Exception:
            pass

        # 运行时数据：桥接客户端与待更新状态
        self._bridge_client: WebSocketBridgeClient | None = None
        self._pending_status: dict | None = None
        self._last_ui_update_ts: float = 0.0
        # UI刷新定时器（限制刷新频率在约10fps，满足性能要求）
        self._ui_timer = QTimer(self)
        self._ui_timer.setInterval(100)
        self._ui_timer.timeout.connect(self._flush_pending_status)
        self._ui_timer.start()

        # 每5秒自动清空的状态键（默认清空车辆速度与避让状态）
        self._auto_clear_keys = ["robotspeed", "obs"]
        self._auto_clear_interval_ms = 5000
        self._clear_timer = QTimer(self)
        self._clear_timer.setInterval(self._auto_clear_interval_ms)
        self._clear_timer.timeout.connect(self._clear_pending_status_keys)
        self._clear_timer.start()

    def _update_connect_button_text(self, checked: bool) -> None:
        """更新连接按钮文本（界面展示用）。"""
        text = self.language_manager.get_text(
            "car_status_connect_button_disconnect" if checked else "car_status_connect_button_connect",
            "断开" if checked else "连接",
        )
        self.connect_button.setText(text)

    def _on_connect_toggled(self, checked: bool) -> None:
        """连接/断开开关事件：启动或停止WebSocket桥接客户端。"""
        # 更新按钮文本
        self._update_connect_button_text(checked)
        if checked:
            # 启动桥接客户端
            ip = (self.ip_edit.text() or "").strip()
            if not ip:
                # 无IP，回退为未选中状态
                self.connect_button.setChecked(False)
                logger.warning("未输入车辆IP，无法连接")
                return
            # 若已有客户端，先停止
            if self._bridge_client:
                try:
                    self._bridge_client.stop()
                    self._bridge_client.wait(2000)
                except Exception:
                    pass
                self._bridge_client = None
            # 创建并启动新客户端
            self._bridge_client = WebSocketBridgeClient(ip_address=ip, parent=self)
            try:
                self._bridge_client.status_changed.connect(self._on_status_changed)
                self._bridge_client.connection_status.connect(self._on_connection_status)
                self._bridge_client.error.connect(self._on_bridge_error)
            except Exception:
                pass
            try:
                logger.info(f"尝试连接车辆WebSocket: {ip}")
                self._bridge_client.start()
            except Exception:
                # 启动失败则恢复开关状态
                self.connect_button.setChecked(False)
                self._bridge_client = None
                logger.error("WebSocket桥接客户端启动失败")
        else:
            # 停止桥接客户端
            if self._bridge_client:
                try:
                    self._bridge_client.stop()
                    self._bridge_client.wait(2000)
                except Exception:
                    pass
                self._bridge_client = None
            logger.info("已停止车辆状态连接")

    def _on_status_changed(self, status: dict) -> None:
        """接收桥接客户端的状态更新（线程安全信号回调）。"""
        # 保存最新状态，等待定时器批量刷新UI
        try:
            self._pending_status = dict(status or {})
            # 轻量日志：记录收到状态更新
            logger.debug("车辆状态字典更新已入队")
        except Exception:
            self._pending_status = None

    def _flush_pending_status(self) -> None:
        """定时刷新UI，限制刷新频率避免过度重绘。"""
        if not self._pending_status:
            return
        now = time.monotonic()
        # 控制刷新频率（约10fps）
        if now - self._last_ui_update_ts < 0.09:
            return
        self._last_ui_update_ts = now
        data = self._pending_status
        # 更新标签文本（逐项防护，避免单项错误影响整体刷新）
        try:
            rid = data.get("robotid")
            self.label_robotid.setText(str(rid) if rid is not None else "—")
        except Exception:
            pass
        try:
            ver = data.get("robotverion")
            self.label_robotverion.setText(str(ver) if ver is not None else "—")
        except Exception:
            pass
        try:
            spd = data.get("robotspeed")
            if spd is None:
                self.label_robotspeed.setText("—")
            else:
                self.label_robotspeed.setText(f"{float(spd):.2f} m/s")
        except Exception:
            pass
        try:
            obs = data.get("obs")
            self.label_obs.setText(str(obs) if obs else "—")
        except Exception:
            pass
        try:
            chg = data.get("charge")
            if chg is None:
                self.label_charge.setText("—")
            else:
                self.label_charge.setText(f"{int(chg)}%")
        except Exception:
            pass
        try:
            err = data.get("errorcode")
            self.label_errorcode.setText(str(err) if err else "—")
        except Exception:
            pass
        # 刷新完成后清空待处理状态，避免重复更新
        self._pending_status = None

    def _clear_pending_status_keys(self) -> None:
        if not self._auto_clear_keys:
            return
        if not self._pending_status:
            return
        try:
            changed = False
            for k in list(self._auto_clear_keys):
                if k in self._pending_status:
                    self._pending_status[k] = None
                    changed = True
            if changed:
                logger.debug("已清空部分状态键")
        except Exception:
            pass

    def set_auto_clear_keys(self, keys: list) -> None:
        try:
            self._auto_clear_keys = [str(k) for k in (keys or []) if k is not None]
        except Exception:
            self._auto_clear_keys = []

    def set_auto_clear_interval(self, ms: int) -> None:
        try:
            v = int(ms)
            if v <= 0:
                return
            self._auto_clear_interval_ms = v
            self._clear_timer.setInterval(v)
        except Exception:
            pass

    def _on_connection_status(self, ok: bool, reason: str) -> None:
        """桥接客户端连接状态通知。"""
        try:
            if ok:
                logger.info(f"车辆状态连接成功: {reason}")
            else:
                logger.warning(f"车辆状态连接断开/重试: {reason}")
        except Exception:
            pass

    def _on_bridge_error(self, message: str) -> None:
        """桥接客户端错误通知。"""
        try:
            logger.error(f"车辆状态桥接错误: {message}")
        except Exception:
            pass

    def closeEvent(self, event) -> None:
        """窗口关闭事件：确保桥接客户端停止，避免线程泄漏。"""
        try:
            if self._bridge_client:
                self._bridge_client.stop()
                self._bridge_client.wait(2000)
                self._bridge_client = None
        except Exception:
            pass
        super().closeEvent(event)